package org.example.controller;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayOpenPublicTemplateMessageIndustryModifyRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayOpenPublicTemplateMessageIndustryModifyResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.example.config.AlipayConfig;
import org.example.config.PayUrlConfig;
import org.example.constants.CacheKey;
import org.example.enums.BizCodeEnum;
import org.example.enums.ClientType;
import org.example.enums.ProductOrderPayTypeEnum;
import org.example.enums.ProductOrderTypeEnum;
import org.example.interceptor.LoginInterceptor;
import org.example.model.PageResult;
import org.example.request.ConfirmOrderRequest;
import org.example.request.RepayOrderRequest;
import org.example.service.ProductOrderService;
import org.example.util.CommonUtil;
import org.example.util.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author LinN
 * @since 2022-10-12
 */
@Slf4j
@Api(tags = "订单模块")
@RestController
@RequestMapping("/api/order/v1")
public class ProductOrderController {

    @Autowired
    private ProductOrderService orderService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @ApiOperation("获取下单token")
    @GetMapping("get_token")
    public JsonData getOrderToken() {
        Long userId = LoginInterceptor.threadLocal.get().getId();
        String key = String.format(CacheKey.SUBMIT_ORDER_TOKEN, userId);
        String token = CommonUtil.getStringNumRandom(32);
        redisTemplate.opsForValue().set(key, token, 30, TimeUnit.MINUTES);
        return JsonData.buildSuccess(token);
    }

    @ApiOperation("二次支付")
    @GetMapping("repay")
    public void repay(@ApiParam("二次支付请求对象") @RequestBody RepayOrderRequest repayOrderRequest,
                      HttpServletResponse response) {
        JsonData jsonData = orderService.repay(repayOrderRequest);
        if (jsonData.getCode() == 0) {
            String client = repayOrderRequest.getClientType();
            String payType = repayOrderRequest.getPayType();
            if (payType.equalsIgnoreCase(ProductOrderPayTypeEnum.ALIPAY.name())) {
                log.info("创建支付宝订单成功:{}", repayOrderRequest.toString());
                // 如果是支付宝网页支付，都是跳转网页，APP除外
                if (client.equalsIgnoreCase(ClientType.H5.name())) {
                    writeData(response, jsonData);
                } else if (client.equalsIgnoreCase(ClientType.APP.name())) {
                    //APP SDK支付 TODO
                }
            } else if (payType.equalsIgnoreCase(ProductOrderPayTypeEnum.WECHAT.name())) {
                log.info("创建微信订单成功:{}", repayOrderRequest.toString());
                //TODO
            }
        } else {
            CommonUtil.sendJsonMessage(response, jsonData.toString());
            log.error("创建订单失败");
        }
    }

    @ApiOperation("根据支付状态分页查询订单")
    @GetMapping("page")
    public JsonData getPageByState(@ApiParam("页码") @RequestParam(value = "page", defaultValue = "1") Integer page,
                                   @ApiParam("每页显示多少条") @RequestParam(value = "size", defaultValue = "10") Integer size,
                                   @ApiParam("状态") @RequestParam(value = "state", required = false) String state) {
        PageResult pageResult = orderService.getPageByState(page, size, state);
        return JsonData.buildSuccess(pageResult);
    }


    @ApiOperation("查询订单状态")
    @GetMapping("query_state")
    public JsonData queryOrderState(@ApiParam("订单号") @RequestParam("out_trade_no") String outTradeNo) {
        String state = orderService.queryOrderState(outTradeNo);
        return StringUtils.isBlank(state) ? JsonData.buildResult(BizCodeEnum.ORDER_CONFIRM_NOT_EXIST) : JsonData.buildSuccess(state);
    }

    @ApiOperation("提交订单")
    @GetMapping("confirm")
    public void confirmOrder(@ApiParam("订单对象") @RequestBody ConfirmOrderRequest orderRequest, HttpServletResponse response) {
        JsonData jsonData = orderService.confirmOrder(orderRequest);
        if (jsonData.getCode() == 0) {
            String client = orderRequest.getClientType();
            String payType = orderRequest.getPayType();
            if (payType.equalsIgnoreCase(ProductOrderPayTypeEnum.ALIPAY.name())) {
                log.info("创建支付宝订单成功:{}", orderRequest.toString());
                // 如果是支付宝网页支付，都是跳转网页，APP除外
                if (client.equalsIgnoreCase(ClientType.H5.name())) {
                    writeData(response, jsonData);
                } else if (client.equalsIgnoreCase(ClientType.APP.name())) {
                    //APP SDK支付 TODO
                }
            } else if (payType.equalsIgnoreCase(ProductOrderPayTypeEnum.WECHAT.name())) {
                log.info("创建微信订单成功:{}", orderRequest.toString());
                //TODO
            }
        } else {
            CommonUtil.sendJsonMessage(response, jsonData.toString());
            log.error("创建订单失败");
        }
    }

    /**
     * 将jsonData输出到页面
     */
    private void writeData(HttpServletResponse response, JsonData jsonData) {
        try {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write(jsonData.getData().toString());
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            log.error("写出html异常:{}", e);
            e.printStackTrace();
        }
    }

    @Autowired
    private PayUrlConfig payUrlConfig;

    /**
     * 支付测试接口，用完记得删
     */
    @GetMapping("test_pay")
    public void testAlipay(HttpServletResponse servletResponse) throws AlipayApiException, IOException {
        AlipayClient alipayClient = AlipayConfig.getInstance();
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        /**
         * 等等需要转化为json数据
         */
        HashMap<String, String> content = new HashMap<>();
        String no = UUID.randomUUID().toString();
        log.info("订单号:{}", no);
        content.put("out_trade_no", no);
        content.put("product_code", "FAST_INSTANT_TRADE_PAY");
        //订单总金额，单位为元，精确到小数点后两位
        content.put("total_amount", String.valueOf("111.99"));
        //商品标题/交易标题/订单标题/订单关键字等。 注意：不可使用特殊字符，如 /，=，&amp; 等。
        content.put("subject", "杯子");
        //商品描述，可空
        content.put("body", "好的杯子");
        // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        content.put("timeout_express", "5m");
        request.setBizContent(JSON.toJSONString(content));
        request.setNotifyUrl(payUrlConfig.getCallbackUrl());
        request.setReturnUrl(payUrlConfig.getAlipaySuccessReturnUrl());
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            String form = response.getBody();
            System.out.println("form=" + form);
            servletResponse.setContentType("text/html;charset=UTF-8");
            servletResponse.getWriter().write(form);
            servletResponse.getWriter().flush();
            servletResponse.getWriter().close();
        } else {
            System.out.println("调用失败");
        }
    }
}

